package com.bwstudio.common.unires.handler;

import javax.servlet.http.HttpServletRequest;

import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import com.bwstudio.common.response.Result;
import com.bwstudio.common.unires.annotation.ResponseResult;
import com.bwstudio.common.unires.interceptor.ResponseResultInterceptor;
import com.google.gson.Gson;

import lombok.extern.slf4j.Slf4j;

/**
 * 接口响应体处理器
 * 
 * @author buwei
 *
 */
@Slf4j
@ControllerAdvice
@ConditionalOnBean({ ResponseResultInterceptor.class }) // 这个注解表示只有ResponseResultInterceptor注入在spring容器中，该类才会被注入
public class ResponseResultHandler implements ResponseBodyAdvice<Object> {

	/**
	 * 标记名称
 	 */
	public static final String RESPONSE_RESULT_ANN = "RESPONSE-RESULT-ANN";

	@Override
	public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
		ServletRequestAttributes sra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
		HttpServletRequest request = sra.getRequest();
		// 判断请求，是否有包装标记
		ResponseResult responseResultAnn = (ResponseResult) request.getAttribute(RESPONSE_RESULT_ANN);
		return responseResultAnn == null ? false : true;
	}

	@Override
	public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,
								  Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request,
								  ServerHttpResponse response) {
//		log.info(" 进入 返回体 重写格式 处理中。。。。。。");

		/*
		 * if(body instanceof ErrorResult) { log.info(" 返回值 异常 作包装 处理中。。。。。。");
		 * ErrorResult errorResult = (ErrorResult) body; return
		 * Result.failure(errorResult.get, body); }
		 */
//		return Result.success(body);
		
		// 对于返回的对象如果不是最终对象ResponseResult，则选包装一下
		if (!(body instanceof Result)) {
			Result result = Result.success(body);
			// 因为handler处理类的返回类型是String，为了保证一致性，这里需要将ResponseResult转回去
			// 不加下面的String处理语句会在返回值类型为String报错：
			// java.lang.ClassCastException: 。。。ResponseResult cannot be cast to java.lang.String
			if (body instanceof String) {
				Gson gson = new Gson();
				return gson.toJson(result);
			}
			return result;
		}
		return body;
	}

}
